import java.util.Hashtable;
import java.util.Enumeration;

//TODO: Add function definitions to symbol table, differentiate between matrix and func types

public class MPSymbolTable {
	private Hashtable<String,String> tableV;
	private Hashtable<String,String> tableF;
	protected MPSymbolTable outer;
	private int depth;
	
	public MPSymbolTable(MPSymbolTable st) {
		tableV = new Hashtable<String,String>();
		tableF = new Hashtable<String,String>();
		outer = st;
		if (st == null) {
			depth = 1;
		}
		else {
			depth = st.getDepth()+1;
		}
	}
	public MPSymbolTable(MPSymbolTable st, int d) {
		tableV = new Hashtable<String,String>();
		tableF = new Hashtable<String,String>();
		outer = st;
		depth = d;
	}
	public int getDepth() {
		return depth;
	}
	public String getTabs() {
		String str = "";
		for(int i = 0; i < depth; i++) {
			str += "   ";
		}
		return str;
	}
	public void putV(String token) {
		tableV.put(token, "");
	}
	public boolean containsV(String token) {
		for (MPSymbolTable tab = this; tab != null; tab = tab.outer) {
			if (tab.tableV.containsKey(token))
				return true;
		}
		return false;
	}
	public void putF(String token, int numArgs) {
		token = token+numArgs;
		tableF.put(token, "");
	}
	public boolean containsF(String token, int numArgs) {
		token = token+numArgs;
		for (MPSymbolTable tab = this; tab != null; tab = tab.outer) {
			if (tab.tableF.containsKey(token))
				return true;
		}
		return false;
	}
	public void printInScopeVars() {
		System.err.println("In scope identifiers:");
		for (MPSymbolTable tab = this; tab != null; tab = tab.outer) {
			Enumeration<String> keys = tab.tableV.keys();
			while (keys.hasMoreElements()) {
				System.err.println(keys.nextElement());
			}
			System.err.println("------");
		}
	}
	public void printInScopeFuncs() {
		System.err.println("In scope functions:");
		for (MPSymbolTable tab = this; tab != null; tab = tab.outer) {
			Enumeration<String> keys = tab.tableF.keys();
			while (keys.hasMoreElements()) {
				System.err.println(keys.nextElement());
			}
			System.err.println("------");
		}
	}

}